package cn.rkylin.oms.common.event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;

/**
 * 简单事件总线
 * 
 * @author wangxiaoyi
 * @since 2017年4月13日 3:44
 */

@SuppressWarnings("rawtypes")
public class SimpleEventBus implements IEventBus {
	private final Map<EventTypeCodeEnum, List<EventHandler>> map = new HashMap();

	@SuppressWarnings("unchecked")
	@Override
	public <H extends EventHandler> void addHandler(EventTypeCodeEnum type, H handler, boolean isDefer) {
		Assert.notNull(handler, "参数handler必须");
		Assert.notNull(type, "参数typer必须");
		List<EventHandler> handlers = map.get(type);
		if (handlers == null) {
			handlers = createEmptyHandlers();
			map.put(type, handlers);
		}
		handlers.add(handler);
		Collections.sort(handlers, comparator);
	}

	@Override
	public void fireEvent(BusinessEvent<EventHandler> event) throws Exception {
		Assert.notNull(event, "参数evvent必须");
		List<EventHandler> handlers = map.get(event.getAssociatedType());
		if (handlers == null) {
			return;
		}
		for (EventHandler handler : handlers) {
			event.dispatch(handler);
		}
	}

	@Override
	public EventHandler getHandler(EventTypeCodeEnum type, int index) {
		List<EventHandler> handlers = map.get(type);
		return handlers.toArray(new EventHandler[handlers.size() - 1])[index];
	}

	@Override
	public int getHandlerCount(EventTypeCodeEnum type) {
		List<EventHandler> handlers = map.get(type);
		return handlers.size();
	}

	private List createEmptyHandlers() {
		return new ArrayList<EventHandler>();
	}

	private Comparator comparator = new Comparator<EventHandler>() {
		@Override
		public int compare(EventHandler o1, EventHandler o2) {
			int thisVal = o1.getPosition();
			int anotherVal = o2.getPosition();
			return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
		}
	};
}
